on exit
code, and leaves the
guard
construct.
If an exception is reported during execution of the guarded
code, the system stops executing the guarded code, executes
the on exit
code, then looks for all clauses in
the catch list that catch the reported exception. For each
clause in the catch list that catches the reported exception,
the specified consequence occurs.
If any expression in the catching
part of the
guard
construct uses the caught
keyword, ScriptX immediately exits from the guard
construct. None of the remaining statements in the current
catch list or any surrounding catch lists are executed.
After ScriptX has checked the clauses in the current catch
list, it reports (throws) the exception again, which means it
checks for catch lists in any surrounding guard
construct.
If any clause that catches the exception uses the throw
again
construct, the system throws the exception again
immediately. In this case, it does not check the remaining
statements in the catch list of the current guard
construct, but immediately moves on to the surrounding one.
The system continues throwing the exception until the
exception is explicitly caught by the caught
construct. If the exception is not caught, if the
caught
construct is not specified for that
exception, then the thread that was running when the exception
occurred dies. If the exception occurs in the main thread, the
title quits. Imagine the exception bouncing around from
catcher to catcher until either something finally catches it
for good, or it falls to the ground uncaught.
guard
construct, through the
catching
list, can catch individual exceptions,
instances of a class of exceptions, or all exceptions.
To catch a particular exception, specify the
Exception
instance in the catch list. For
example, this line catches only the divideByZero
exception:
catching
divideByZero : print "Divide by zero error. \n"
To catch all instances of a class of exception, specify the
exception class in the catching list. For example, this line
catches all reported math exceptions, including
divideByZero
, lossOfRange
,
invalidNumber
, and any other exceptions that are
instances of the class MathException
.
catching
MathException : print "Some kind of math error."
To catch all exceptions, specify the all
keyword
in the catch list. For example, this line catches all reported
exceptions, including both system-defined exceptions and
user-defined exceptions.
catching
all : print "Look out, there's an error about."
During the execution of the guarded expressions, several kinds
of exceptions could occur. First, the width
or
length
might not be defined on box1
.
Secondly, the values of those instance variables might be
undefined
or some other non-numeric value.
Finally, the length of the box might actually be
0
.
width
or length
instance variable is not defined for box1
, that
variable does not have a setter or getter method, and so a
noMethod
exception is reported (for example "no
lengthGetter
method for Box
"). The
remaining expressions in the guarded code are not executed.
First, the on exit
code is executed. The
exception is then intercepted and handled by the first clause
in the catch list, which prints the message "There's a
method missing."
to the debug
stream.
box1
is an object that implements both the
length
and width
instance variables,
but length
contains 0
, the second
expression in the guarded code reports a
divideByZero
exception, since the
ratio
expression attempted to divide the value of
width
by zero. The on exit
code is
executed. The exception is intercepted and handled by the
second clause in the catch list, and the message "Divide
by zero error."
is printed. The exception is also
intercepted and processed by the third clause, since the
divideByZero
exception is an instance of the
class MathException
. The message "Some kind
of math error."
is also printed.
box1
is an object that implements both the
length
and width
instance variables,
but either one contains a non-number value, the third
expression reports the invalidNumber
exception.
The on
exit
code is executed. The
exception is intercepted and handled by the third clause in
the catch
list, since the
invalidNumber
exception is an instance of the
class MathException
. The message "Some kind
of math error."
is printed.
all
). Since the exception has been caught,
no more catchers in the catch list, or in any catch lists of
surrounding guard
expressions, are executed. The
value of the guard
expression is
undefined
. Since the expression was finally
caught, execution continues after the outermost
guard
expression.guard
expression can consist of or include other guard
expressions. The use of multiple guard
levels
enables you to tune your exception-catching code. For example,
you can write code that checks all expressions in a block for
exceptions of type e1, additionally checks a subset
of the expressions for exceptions of type e2, and
checks a further subset for exceptions of type e3.
Usually, when an exception is reported by a guarded
expressions in a guard
construct, ScriptX checks
each of the clauses in the catch list to find which ones catch
the exception. Each exception in the catch list is checked,
even if one has already caught the exception (unless one of
the expressions uses the caught
or throw
again
construct as discussed in "How to Control Throwing and Catching"
on page 178.)
caught
construct, in which case the system exits
from the outermost guard
expression and continues
executing the program.
guard
expressions work.
S1
and S2
represent ScriptX
expressions that can be guarded. The symbols e1
,
e2
, e3
, e4
, and
e5
represent lexical names, either instances of
Exception
or exception classes. In this example,
expression S1
is guarded against exceptions
e4
and e5
, while expression
S2
is guarded against exceptions e1
,
e2
, e3
, e4
, and
e5
.
Consider what happens if S1
reports an
exception:
guard
expression and checks if the reported
exception is an instance of e4
. If so, it
executes the expression repair D
and continues
with the next catcher in the list.
e5
. If so, it executes the expression
repair E
and continues with the next catcher in
the list, which is an all
clause.
all: caught undefined
explicitly
catches the exception and prevents it from being thrown again.
guard
expression and executes the expression S3
.
S2
reports an
exception:e1
. If so, it executes the expression
repair A
and continues with the next catcher in
the list.
e2
. If so, it executes the expression
repair B
and continues with the next catcher in
the list.
e3
. If so, it executes the expression
repair C
and continues with the next catcher in
the list.
guard
expression if
there is one, which there is.
guard
expression and checks if the reported
exception is an instance of e4
. If so, it
executes the expression repair D
and continues
with the next catcher in the list.
e5
. If so, it executes the expression
repair E
and continues with the next catcher in
the list, which is an all
clause.
all: caught undefined
explicitly
catches the exception and prevents it from being thrown again.
guard
expression and executes the expression S3
.
all
clause. This clause is
really just a macro that expands to Exception
-it
is a shorthand way of intercepting all
instances
of Exception
. Note that there is no particular
reason, although the examples in this chapter show it, that
the all
clause has to be last in the catch list.
A catch list can have no all
clause, or it can
have several.
This document is part of the ScriptX Language Guide, one of the volumes of the ScriptX Technical Reference Series. ScriptX is developed by the ScriptX Engineering Team at Apple Computer, successor to the Kaleida Engineering Team at Kaleida Labs, Inc.